package com.ilink.groundservice.service.impl.AiX;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ilink.groundservice.entity.PO.AiX.AiXDelete;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneAchievement;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneAuthor;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneBase;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneBeginEnd;
import com.ilink.groundservice.entity.PO.AiX.AiXScenePhaseBase;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneSignUp;
import com.ilink.groundservice.entity.PO.AiX.AiXSceneStartLearn;
import com.ilink.groundservice.entity.PO.AiX.AiXTag;
import com.ilink.groundservice.entity.PO.AiX.AiXTagConnect;
import com.ilink.groundservice.entity.VO.AiX.AiXAuthorResponse;
import com.ilink.groundservice.entity.VO.AiX.AiXSceneResponse;
import com.ilink.groundservice.mapper.AiX.AiXDeleteMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneAchievementMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneAuthorMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneBeginEndMapper;
import com.ilink.groundservice.mapper.AiX.AiXScenePhaseBaseMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneSignUpMapper;
import com.ilink.groundservice.mapper.AiX.AiXSceneStartLearnMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagConnectMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagMapper;
import com.ilink.groundservice.service.AiX.AiXSceneService;
import com.ilink.groundservice.mapper.AiX.AiXSceneBaseMapper;
import com.ilink.ilinkapi.client.UserServiceClient;
import com.ilink.ilinkapi.dto.ground.AiX.AiXAreaFilterRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSceneBaseUpdateRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSceneCardInsertRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXSceneCardUpdateRequest;
import com.ilink.ilinkcommon.domain.R;
import com.ilink.ilinkcommon.domain.User;
import com.ilink.ilinkcommon.service.oss.MinioService;
import com.ilink.ilinkcommon.utils.BeanUtils;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
* @author Zhangbo
* @description 针对微场景的增删改查
* @createDate 2025-01-15 10:21:24
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class AiXSceneServiceImpl extends ServiceImpl<AiXSceneBaseMapper, AiXSceneBase>
    implements AiXSceneService {
    private final AiXSceneBaseMapper aiXSceneBaseMapper;
    private final AiXSceneAchievementMapper aiXSceneAchievementMapper;
    private final AiXSceneAuthorMapper aiXSceneAuthorMapper;
    private final AiXScenePhaseBaseMapper aiXScenePhaseBaseMapper;

    private final AiXSceneBeginEndMapper aiXSceneBeginEndMapper;
    private final AiXSceneStartLearnMapper aiXSceneStartLearnMapper;
    private final AiXSceneSignUpMapper aiXSceneSignUpMapper;

    private final AiXTagMapper aiXTagMapper;
    private final AiXTagConnectMapper aiXTagConnectMapper;
    private final AiXDeleteMapper aiXDeleteMapper;

    private final MinioService minioService;
    private final UserServiceClient userServiceClient;

    /**
     * @Author ZhangBo
     * @Description 分页获取微场景卡片
     * @Date 16:48 2025/1/15
     * @Param [request]
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.ilink.groundservice.entity.VO.AiX.AiXSceneResponse>
     **/
    @Override
    public IPage<AiXSceneResponse> getScenes(AiXAreaFilterRequest request, String userId) {
        try{
            // 创建分页对象
            Page<AiXSceneBase> page = new Page<>(request.getPage(), request.getSize());

            // 构建查询条件
            LambdaQueryWrapper<AiXSceneBase> queryWrapper = new LambdaQueryWrapper<>();

            // 匹配场景区域
            queryWrapper.eq(request.getAreaId() != null, AiXSceneBase::getAreaId, request.getAreaId());

            // 对于已发布的场景或用户有权限查看的未发布场景进行查询
            queryWrapper.and(wrapper -> {
                wrapper.eq(AiXSceneBase::getIsPublish, 1);  // 已发布的场景

                // 查询所有未发布的场景
                List<AiXSceneBase> unpublishedScenes = aiXSceneBaseMapper.selectList(
                    new LambdaQueryWrapper<AiXSceneBase>()
                        .eq(AiXSceneBase::getIsPublish, 0)
                );

                // 检查每个未发布场景的权限
                List<Long> authorizedSceneIds = unpublishedScenes.stream()
                    .filter(scene -> {
                        R permissions = userServiceClient.checkUserScenePermission(userId, scene.getSceneId());
                        Map<String, Boolean> permissionsMap = (Map<String, Boolean>) permissions.getData();
                        return permissionsMap != null && permissionsMap.get("view");
                    })
                    .map(AiXSceneBase::getSceneId)
                    .collect(Collectors.toList());

                // 如果有授权的未发布场景，添加到查询条件中
                if (!authorizedSceneIds.isEmpty()) {
                    wrapper.or(w -> w.in(AiXSceneBase::getSceneId, authorizedSceneIds));
                }
            });

            // 匹配标签
            if (request.getTag() != null && !request.getTag().isEmpty()) {
                List<Long> sceneIdsWithTag = aiXTagConnectMapper.selectList(
                    new LambdaQueryWrapper<AiXTagConnect>().eq(AiXTagConnect::getTagId,
                        aiXTagMapper.selectOne(new LambdaQueryWrapper<AiXTag>().eq(AiXTag::getTagName, request.getTag()).last("LIMIT 1")).getTagId())
                ).stream().map(AiXTagConnect::getConnectTableKey).collect(Collectors.toList());

                if (!sceneIdsWithTag.isEmpty()) {
                    queryWrapper.in(AiXSceneBase::getSceneId, sceneIdsWithTag);
                } else {
                    return new Page<>(request.getPage(), request.getSize()); // 如果没有匹配的标签，返回空结果
                }
            }

            // 匹配标题和介绍
            if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
                queryWrapper.and(wrapper ->
                    wrapper.like(AiXSceneBase::getSceneTitle, request.getKeyword())  // 匹配场景标题
                        .or().like(AiXSceneBase::getIntroduction, request.getKeyword())  // 匹配场景介绍
                );
            }

            // 执行查询
            IPage<AiXSceneBase> scenePage = aiXSceneBaseMapper.selectPage(page, queryWrapper);

            // 拼接响应
            List<AiXSceneResponse> responseList = scenePage.getRecords().stream()
                .map(scene -> {
                    AiXSceneResponse response = new AiXSceneResponse();
                    response.setSceneId(scene.getSceneId());
                    response.setSceneTitle(scene.getSceneTitle());
                    response.setIntroduction(scene.getIntroduction());
                    response.setIsPublish(scene.getIsPublish());
                    String imageUrl = minioService.getBucketFileUrl("dataset-square-migrate",scene.getCoverUrl());
                    if(imageUrl != null){
                        response.setCoverUrl(imageUrl);
                    }
                    response.setAreaId(scene.getAreaId());

                    // 处理出品人信息
                    List<AiXSceneAuthor> sceneAuthors = aiXSceneAuthorMapper.selectList(
                        new LambdaQueryWrapper<AiXSceneAuthor>().eq(AiXSceneAuthor::getSceneId, scene.getSceneId())
                    );

                    List<AiXAuthorResponse> authorsResponseList = sceneAuthors.stream()
                        .map(author -> getUserInfoById(author.getUserId()))  // 获取用户所有信息
                        .filter(Objects::nonNull)  // 过滤掉为空的用户信息
                        .collect(Collectors.toList());

                    response.setAuthors(authorsResponseList);  // 出品人详细信息列表

                    // 获取奖励
                    response.setReward(scene.getReward());

                    // 获取活动标签并转换为字符串列表
                    List<AiXTagConnect> tagConnects = aiXTagConnectMapper.selectList(new LambdaQueryWrapper<AiXTagConnect>().eq(AiXTagConnect::getConnectTableKey, scene.getSceneId()));
                    List<String> tags = tagConnects.stream()
                        .map(tagConnect -> aiXTagMapper.selectById(tagConnect.getTagId()).getTagName())
                        .collect(Collectors.toList());
                    response.setTags(tags); // 设置标签列表

                    // 获取成就
                    List<AiXSceneAchievement> sceneAchievements = aiXSceneAchievementMapper.selectList(
                        new LambdaQueryWrapper<AiXSceneAchievement>().eq(AiXSceneAchievement::getSceneId, scene.getSceneId())
                    );
                    List<String> achievements = sceneAchievements.stream().map(AiXSceneAchievement::getAchievement).collect(Collectors.toList());
                    response.setAchievement(achievements); // 成就列表

                    // 查询场景的起止时间
                    AiXSceneBeginEnd sceneBeginEnd = aiXSceneBeginEndMapper.selectOne(
                        new LambdaQueryWrapper<AiXSceneBeginEnd>()
                            .eq(AiXSceneBeginEnd::getSceneId, scene.getSceneId())
                            .last("LIMIT 1") // 强制限制查询返回最多一条记录
                    );
                    if (sceneBeginEnd != null) {
                        response.setStartTime(sceneBeginEnd.getStartTime());  // 设置起始时间
                        response.setEndTime(sceneBeginEnd.getEndTime());      // 设置结束时间
                    }

                    return response;
                })
                .collect(Collectors.toList());

            // 创建分页响应
            Page<AiXSceneResponse> responsePage = new Page<>(scenePage.getCurrent(), scenePage.getSize(), scenePage.getTotal());
            responsePage.setRecords(responseList);

            return responsePage;
        } catch (Exception e) {
            log.error("分页查询getScenes错误" + e.getMessage());
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 根据sceneId查询场景基本信息
     * @Date 14:39 2025/1/20
     * @Param [sceneId]
     * @return com.ilink.groundservice.entity.VO.AiX.AiXSceneResponse
     **/
    @Override
    public AiXSceneResponse getSceneById(Long sceneId) {
        try{
            // 根据sceneId查询场景基本信息
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
            if (scene == null) {
                // 如果场景不存在，返回 null 或错误信息
                log.error("场景未找到，sceneId: " + sceneId);
                return null; // 可以根据需求调整返回值，例如返回错误信息
            }

            // 拼接响应
            AiXSceneResponse response = new AiXSceneResponse();
            response.setSceneId(scene.getSceneId());
            response.setSceneTitle(scene.getSceneTitle());
            response.setIntroduction(scene.getIntroduction());
            String imageUrl = minioService.getBucketFileUrl("dataset-square-migrate",scene.getCoverUrl());
            if(imageUrl != null){
                response.setCoverUrl(imageUrl);
            }
            response.setAreaId(scene.getAreaId());
            response.setReward(scene.getReward());  // 奖励信息

            // 处理出品人信息
            List<AiXSceneAuthor> sceneAuthors = aiXSceneAuthorMapper.selectList(
                new LambdaQueryWrapper<AiXSceneAuthor>().eq(AiXSceneAuthor::getSceneId, scene.getSceneId())
            );

            List<AiXAuthorResponse> authorsResponseList = sceneAuthors.stream()
                .map(author -> getUserInfoById(author.getUserId()))  // 获取用户所有信息
                .filter(Objects::nonNull)  // 过滤掉为空的用户信息
                .collect(Collectors.toList());

            response.setAuthors(authorsResponseList);  // 出品人详细信息列表

            // 使用 AiXTagConnect 获取标签
            List<AiXTagConnect> tagConnects = aiXTagConnectMapper.selectList(
                new LambdaQueryWrapper<AiXTagConnect>()
                    .eq(AiXTagConnect::getConnectTableKey, sceneId)
                    .eq(AiXTagConnect::getConnectTable, "ai_x_scene")
            );

            List<AiXTag> tags = tagConnects.stream()
                .map(tagConnect -> aiXTagMapper.selectById(tagConnect.getTagId()))
                .collect(Collectors.toList());
            response.setTags(tags.stream().map(AiXTag::getTagName).collect(Collectors.toList()));


            // 获取成就
            List<AiXSceneAchievement> sceneAchievements = aiXSceneAchievementMapper.selectList(
                new LambdaQueryWrapper<AiXSceneAchievement>().eq(AiXSceneAchievement::getSceneId, scene.getSceneId())
            );
            List<String> achievements = sceneAchievements.stream().map(AiXSceneAchievement::getAchievement).collect(Collectors.toList());
            response.setAchievement(achievements); // 成就列表

            return response;
        } catch (Exception e) {
            log.error("查询单个微场景getSceneById错误" + e.getMessage());
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 新增微场景卡片
     * @Date 14:59 2025/1/15
     * @Param [request]
     * @return com.ilink.ilinkcommon.domain.R
     **/
    @Override
    @Transactional
    public R insertScene(String userId, AiXSceneCardInsertRequest request) {
        try {
            // 使用雪花算法生成sceneId
            SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
            Long sceneId = idGenerator.nextId(); // 生成 sceneId
            AiXSceneBase scene = new AiXSceneBase();
            scene.setSceneId(sceneId);
            if(request.getSceneTitle().isEmpty()){
                scene.setSceneTitle("您可以在此处输入微场景的名称");
            }
            else{
                scene.setSceneTitle(request.getSceneTitle());
            }
            scene.setReward(request.getReward()); // 设置参加可得，+分隔
            scene.setAreaId(request.getAreaId());
            scene.setIntroduction("您可以在此处输入微场景介绍，包括背景、问题描述及目标等内容，字数不超过500字");

            // 上传封面图片到 OSS
            String objectName = "area/" + request.getAreaId() + "/scene/" + sceneId + getFileExtension(request.getCoverImage().getOriginalFilename());

            boolean isUploaded = minioService.uploadBucketFile(request.getCoverImage(), "dataset-square-migrate", objectName);
            if (!isUploaded) {
                return R.error("场景封面上传失败");
            }
            scene.setCoverUrl(objectName); // 设置封面地址

            aiXSceneBaseMapper.insert(scene); // 插入场景

            // 新增一个出品人
            AiXSceneAuthor author = new AiXSceneAuthor();
            author.setSceneAuthorId(idGenerator.nextId());
            author.setUserId(userId);
            author.setSceneId(sceneId);
            aiXSceneAuthorMapper.insert(author);

            // 插入一条开课记录
            AiXSceneBeginEnd beginEnd = new AiXSceneBeginEnd();
            beginEnd.setBeginEndId(idGenerator.nextId());
            beginEnd.setSceneId(sceneId);
            beginEnd.setStartTime(request.getStartTime());
            beginEnd.setEndTime(request.getEndTime());
            // 这里先设置为默认值后续再修改
            beginEnd.setRecordName("第1次开课");
            beginEnd.setRecordNumber(1);
            aiXSceneBeginEndMapper.insert(beginEnd);

            // 插入标签
            if (request.getTags() != null) {
                handleTags(request.getTags(), sceneId); // 调用提取的标签处理方法
            }

            // 插入成就
            if (request.getAchievement() != null) {
                for (String achievement : request.getAchievement()) {
                    AiXSceneAchievement sceneAchievement = new AiXSceneAchievement();
                    sceneAchievement.setSceneId(sceneId);
                    sceneAchievement.setAchievement(achievement);
                    sceneAchievement.setAchievementId(idGenerator.nextId()); // 使用雪花算法生成achievementId
                    aiXSceneAchievementMapper.insert(sceneAchievement); // 插入成就
                }
            }

            // 新建一条 AiXScenePhaseBase 阶段数据
            AiXScenePhaseBase scenePhaseBase = new AiXScenePhaseBase();
            scenePhaseBase.setPhaseId(idGenerator.nextId()); // 使用雪花算法生成 phaseId
            scenePhaseBase.setSceneId(sceneId); // 关联当前场景
            scenePhaseBase.setPhaseTitle("暂无"); // 默认标题
            scenePhaseBase.setIntroduction("您可以在此处简要介绍本阶段的技术手段、关键任务及核心内容，字数不超过200字。"); // 默认阶段简介
            scenePhaseBase.setPhaseTarget("您可以在此处详细介绍本阶段目标，包括主要任务、关键技术和预期成果等，字数不超过200字。"); // 默认阶段目标
            scenePhaseBase.setPhaseScore(0); // 默认阶段分数
            scenePhaseBase.setSortOrder(1); // 默认排序号
            scenePhaseBase.setWorkRequirement("您可以在此处输入本阶段作品要求，包括任务目标、数据也可以不要求提交作品。\n"
                + "格式及具体内容等，可以分条阐述，字数不超过200字。");
            scenePhaseBase.setWorkScore(0);
            aiXScenePhaseBaseMapper.insert(scenePhaseBase); // 插入阶段数据

            return R.ok("场景插入成功", sceneId);
        } catch (Exception e) {
            log.error("函数insertScene报错: " + e.getMessage(), e);
            return R.error("场景插入失败");
        }
    }

    /**
     * @Author ZhangBo
     * @Description 更新场景卡片信息
     * @Date 14:39 2025/1/20
     * @Param [request]
     * @return com.ilink.ilinkcommon.domain.R
     **/
    @Override
    @Transactional
    public R updateSceneCard(AiXSceneCardUpdateRequest request) {
        try {
            // 更新场景基本信息
            AiXSceneBase sceneBase = aiXSceneBaseMapper.selectById(request.getSceneId());
            if (sceneBase == null) {
                return R.error("场景不存在");
            }
            
            sceneBase.setSceneTitle(request.getSceneTitle());
            sceneBase.setReward(request.getReward());
            sceneBase.setAreaId(request.getAreaId());
            aiXSceneBaseMapper.updateById(sceneBase);

            // 更新开始结束时间
            AiXSceneBeginEnd beginEnd = aiXSceneBeginEndMapper.selectOne(
                new LambdaQueryWrapper<AiXSceneBeginEnd>()
                    .eq(AiXSceneBeginEnd::getSceneId, request.getSceneId())
            );
            if (beginEnd != null) {
                beginEnd.setStartTime(request.getStartTime());
                beginEnd.setEndTime(request.getEndTime());
                aiXSceneBeginEndMapper.updateById(beginEnd);
            }

            // 删除原有标签关联
            aiXTagConnectMapper.delete(
                new LambdaQueryWrapper<AiXTagConnect>()
                    .eq(AiXTagConnect::getConnectTableKey, request.getSceneId())
                    .eq(AiXTagConnect::getConnectTable, "ai_x_scene")
            );

            // 添加新标签
            if (request.getTags() != null) {
                handleTags(request.getTags(), request.getSceneId());
            }

            // 更新成就
            // 先删除原有成就
            aiXSceneAchievementMapper.delete(
                new LambdaQueryWrapper<AiXSceneAchievement>()
                    .eq(AiXSceneAchievement::getSceneId, request.getSceneId())
            );
            
            // 添加新成就
            if (request.getAchievement() != null) {
                SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
                for (String achievement : request.getAchievement()) {
                    AiXSceneAchievement sceneAchievement = new AiXSceneAchievement();
                    sceneAchievement.setSceneId(request.getSceneId());
                    sceneAchievement.setAchievement(achievement);
                    sceneAchievement.setAchievementId(idGenerator.nextId());
                    aiXSceneAchievementMapper.insert(sceneAchievement);
                }
            }

            return R.ok("场景卡片更新成功");
        } catch (Exception e) {
            log.error("更新场景卡片失败: " + e.getMessage(), e);
            return R.error("更新场景卡片失败");
        }
    }

    /**
     * @Author ZhangBo
     * @Description 更新场景封面
     * @Date 14:39 2025/1/20
     * @Param [file, sceneId, areaId]
     * @return com.ilink.ilinkcommon.domain.R
     **/
    @Override
    @Transactional
    public R updateSceneCover(MultipartFile file, Long sceneId, Long areaId) {
        try {
            // 查询场景对象
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
            if (scene == null) {
                return R.error("场景未找到");
            }

            String objectName = "area/" + areaId + "/scene/" + sceneId + getFileExtension(file.getOriginalFilename());
            
            // 先更新数据库
            scene.setCoverUrl(objectName);
            int result = aiXSceneBaseMapper.updateById(scene);
            if (result <= 0) {
                return R.error("场景封面更新失败");
            }

            // 数据库更新成功后再上传文件
            boolean isUploaded = minioService.uploadBucketFile(file, "dataset-square-migrate", objectName);
            if (!isUploaded) {
                throw new RuntimeException("场景封面上传失败"); // 抛出异常触发事务回滚
            }

            return R.ok("场景封面图更新成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            return R.error(e.getMessage());
        }
    }

    /**
     * @Author ZhangBo
     * @Description 更新微场景基本信息
     * @Date 16:12 2025/1/15
     * @Param [request]
     * @return com.ilink.ilinkcommon.domain.R
     **/
    @Override
    @Transactional
    public R updateSceneBase(AiXSceneBaseUpdateRequest request) {
        // 检查userList是否为空
        if (request.getUserList() == null || request.getUserList().isEmpty()) {
            return R.error("出品人至少保留一条！不可全部删除");
        }
        try {
            // 获取sceneId
            Long sceneId = request.getSceneId();

            // 更新场景的基本信息
            AiXSceneBase scene = new AiXSceneBase();
            scene.setSceneId(sceneId);
            scene.setSceneTitle(request.getSceneTitle());
            scene.setIntroduction(request.getIntroduction());

            aiXSceneBaseMapper.updateById(scene); // 更新场景信息

            // 获取当前场景的所有出品人
            List<AiXSceneAuthor> existingAuthors = aiXSceneAuthorMapper.selectList(new LambdaQueryWrapper<AiXSceneAuthor>().eq(AiXSceneAuthor::getSceneId, sceneId));
            Set<String> existingUserIds = existingAuthors.stream().map(AiXSceneAuthor::getUserId).collect(
                Collectors.toSet());

            Set<String> newUserIds = new HashSet<>(request.getUserList()); // 新的出品人ID列表

            // 处理新的出品人
            if (request.getUserList() != null) {
                for (String userId : request.getUserList()) {
                    if (existingUserIds.contains(userId)) {
                        // 更新已存在的出品人（如果有需要更新的内容）
                        AiXSceneAuthor existingAuthor = existingAuthors.stream()
                            .filter(author -> author.getUserId().equals(userId))
                            .findFirst()
                            .orElse(null);
                        // 更新逻辑可以在此处添加
                        if (existingAuthor != null) {
                            aiXSceneAuthorMapper.updateById(existingAuthor);
                        }
                    } else {
                        // 插入新的出品人
                        AiXSceneAuthor sceneAuthor = new AiXSceneAuthor();
                        sceneAuthor.setSceneId(sceneId);
                        sceneAuthor.setUserId(userId);
                        sceneAuthor.setSceneAuthorId(new SnowflakeIdGenerator(1, 1).nextId()); // 使用雪花算法生成sceneAuthorId
                        aiXSceneAuthorMapper.insert(sceneAuthor); // 插入新的出品人记录
                    }
                }
            }

            // 删除不再存在的出品人
            for (AiXSceneAuthor existingAuthor : existingAuthors) {
                if (!newUserIds.contains(existingAuthor.getUserId())) {
                    aiXSceneAuthorMapper.deleteById(existingAuthor.getSceneAuthorId()); // 删除不再存在的出品人
                }
            }
            return R.ok("场景更新成功");
        } catch (Exception e) {
            log.error("函数updateSceneBase报错: " + e.getMessage(), e);
            return R.error("场景更新失败");
        }
    }


    /**
     * @Author ZhangBo
     * @Description 获取微场景最常用的8个标签
     * @Date 14:41 2025/1/20
     * @Param []
     * @return java.util.List<java.lang.String>
     **/
    @Override
    public List<String> getSceneTags(Long areaId) {
        return aiXTagConnectMapper.getSceneTags(areaId, 8);
    }

    @Override
    @Transactional
    public void deleteScene(Long sceneId) {
        try {
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
            if (scene != null) {
                String coverUrl = scene.getCoverUrl();
                // 查找最后一个斜杠的位置
                int lastSlashIndex = coverUrl.lastIndexOf('/');
                // 使用substring方法进行拆分
                String directory = coverUrl.substring(0, lastSlashIndex + 1);
                String fileName = coverUrl.substring(lastSlashIndex + 1);
                boolean isDeleted = minioService.deleteBucketFile("dataset-square-migrate",directory, fileName);
                if (!isDeleted) {
                    log.error("删除OSS对象失败，微场景ID: {}", sceneId);
                }
                // 删除与活动相关的标签连接记录
                aiXTagConnectMapper.delete(new LambdaQueryWrapper<AiXTagConnect>()
                    .eq(AiXTagConnect::getConnectTableKey, sceneId)
                    .eq(AiXTagConnect::getConnectTable, "ai_x_scene"));
                
                // 在AiXDelete表中插入删除记录
                AiXDelete deleteRecord = new AiXDelete();
                deleteRecord.setDeleteId(new SnowflakeIdGenerator(1, 1).nextId());
                deleteRecord.setDeletePath(String.format("area/%d/scene/%d", scene.getAreaId(), sceneId));
                deleteRecord.setForeignId(sceneId);
                deleteRecord.setForeignName("ai_x_scene");
                aiXDeleteMapper.insert(deleteRecord);
            }

            // 删除数据库条目
            aiXSceneBaseMapper.deleteById(sceneId);
        } catch (Exception e) {
            log.error("删除微场景失败，微场景ID: {}", sceneId, e);
            throw e;
        }
    }

    @Override
    @Transactional
    public R togglePublishStatus(Long sceneId) {
        try {
            // 获取当前场景的信息
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
            if (scene == null) {
                return R.error("未找到该场景，sceneId: " + sceneId);
            }

            // 获取当前 isPublish 的值并取反
            boolean currentPublishStatus = Boolean.TRUE.equals(scene.getIsPublish());
            scene.setIsPublish(!currentPublishStatus);  // 设置为相反的值

            // 执行更新
            aiXSceneBaseMapper.updateById(scene);

            // 返回成功响应
            return R.ok("场景发布状态已更改", !currentPublishStatus);
        } catch (Exception e) {
            log.error("更改场景发布状态失败，sceneId: " + sceneId, e);
            return R.error("更改场景发布状态失败");
        }
    }

    @Override
    public R getScenePublish(Long sceneId) {
        try {
            // 获取当前场景的信息
            AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
            if (scene == null) {
                return R.error("未找到该场景，sceneId: " + sceneId);
            }
            return R.ok("获取场景发布状态成功", scene.getIsPublish());
        } catch (Exception e) {
            log.error("获取场景发布状态失败，sceneId: " + sceneId, e);
            return R.error("获取场景发布状态失败");
        }
    }

    /**
     * @Author ZhangBo
     * @Description 根据用户Id和场景Id更新开始学习表AiXSceneStartLearn和报名表AiXSceneSignUp
     * @Date 17:24 2025/1/19
     * @Param [sceneId, userId]
     * @return com.ilink.ilinkcommon.domain.R
     **/
    @Override
    public R updateStartLearnAndSignUp(Long sceneId, String userId) {
        try {
            // 第一步：查询开课记录表获取最新一期的信息
            AiXSceneBeginEnd beginEnd = aiXSceneBeginEndMapper.selectOne(
                new LambdaQueryWrapper<AiXSceneBeginEnd>()
                    .eq(AiXSceneBeginEnd::getSceneId, sceneId)
                    .orderByDesc(AiXSceneBeginEnd::getRecordNumber)
                    .last("limit 1")
            );
            
            if (beginEnd == null) {
                return R.error("未找到该场景的开课记录");
            }

            // 第二步：检查用户是否已经学习过
            AiXSceneStartLearn existingStartLearn = aiXSceneStartLearnMapper.selectOne(
                new LambdaQueryWrapper<AiXSceneStartLearn>()
                    .eq(AiXSceneStartLearn::getBeginEndId, beginEnd.getBeginEndId())
                    .eq(AiXSceneStartLearn::getUserId, userId)
            );
            
            if (existingStartLearn != null) {
                return R.ok("用户已开始学习该场景");
            }

            // 第三步：判断当前时间是否在起止时间范围内
            Date currentTime = new Date();
            boolean isInTimeRange = currentTime.after(beginEnd.getStartTime()) 
                && currentTime.before(beginEnd.getEndTime());

            // 创建开始学习记录
            AiXSceneStartLearn startLearn = new AiXSceneStartLearn();
            startLearn.setStartLearnId(new SnowflakeIdGenerator(1, 1).nextId());
            startLearn.setBeginEndId(beginEnd.getBeginEndId());
            startLearn.setUserId(userId);
            startLearn.setIsSignUp(0);

            // 如果在时间范围内，还需要创建报名记录
            if (isInTimeRange) {
                startLearn.setIsSignUp(1);
                AiXSceneSignUp signUp = new AiXSceneSignUp();
                signUp.setSignUpId(new SnowflakeIdGenerator(1, 1).nextId());
                signUp.setBeginEndId(beginEnd.getBeginEndId());
                signUp.setUserId(userId);
                signUp.setStartTime(currentTime);
                
                aiXSceneSignUpMapper.insert(signUp);
            }
            aiXSceneStartLearnMapper.insert(startLearn);

            return R.ok("更新学习状态成功");
            
        } catch (Exception e) {
            log.error("更新开始学习和报名状态失败", e);
            return R.error("更新开始学习和报名状态失败");
        }
    }

    @Override
    public List<AiXSceneBeginEnd> getSceneBeginEndRecords(Long sceneId) {
        // 获取所有开课记录
        List<AiXSceneBeginEnd> beginEnds = aiXSceneBeginEndMapper.selectList(new LambdaQueryWrapper<AiXSceneBeginEnd>().eq(AiXSceneBeginEnd::getSceneId, sceneId));
        // 获取所有开课记录的id,如果没找到，返回空list
        if (beginEnds == null) {
            return new ArrayList<>();
        }
        // 对beginEnds进行排序，按照recordNumber倒序
        beginEnds.sort(Comparator.comparing(AiXSceneBeginEnd::getRecordNumber).reversed());
        return beginEnds;
    }


    @Override
    public String getSceneAgentUrl(Long sceneId) {
        AiXSceneBase scene = aiXSceneBaseMapper.selectById(sceneId);
        return scene != null ? scene.getAgentUrl() : null;
    }

    @Override
    public String addSceneAgentUrl(Long sceneId, String agentUrl) {
        // 查询当前场景的智能体 URL
        AiXSceneBase existingScene = aiXSceneBaseMapper.selectById(sceneId);
        if (existingScene != null && existingScene.getAgentUrl() != null) {
            // 如果已存在智能体 URL，返回提示信息和当前的 URL
            return "智能体 URL 已存在: " + existingScene.getAgentUrl();
        }

        // 如果不存在，则更新智能体 URL
        AiXSceneBase scene = new AiXSceneBase();
        scene.setSceneId(sceneId);
        scene.setAgentUrl(agentUrl);
        aiXSceneBaseMapper.updateById(scene);
        
        return getSceneAgentUrl(sceneId);
    }

    @Override
    public String updateSceneAgentUrl(Long sceneId, String agentUrl) {
        AiXSceneBase scene = new AiXSceneBase();
        scene.setSceneId(sceneId);
        scene.setAgentUrl(agentUrl);
        aiXSceneBaseMapper.updateById(scene);
        return getSceneAgentUrl(sceneId);
    }


    /**
     * @Author ZhangBo
     * @Description 获取用户全部信息
     * @Date 10:21 2025/1/17
     * @Param [userId]
     * @return com.ilink.groundservice.entity.VO.AiX.AiXAuthorResponse
     **/
    private AiXAuthorResponse getUserInfoById(String userId) {
        // 获取用户信息
        R whoami = userServiceClient.whoami(userId);
        HttpStatus status = HttpStatus.valueOf(whoami.getCode());

        if (!status.is2xxSuccessful()) {
            log.error(String.format("获取用户信息失败，用户ID: %s", userId));
            return null; // 如果获取用户信息失败，返回 null
        }

        // 获取用户详细信息
        User userDetail = BeanUtils.copyBean(whoami.getData(), User.class);

        // 将用户信息映射到 AiXAuthorResponse
        AiXAuthorResponse authorResponse = new AiXAuthorResponse();
        authorResponse.setUserId(userDetail.getUserId());
        authorResponse.setNickname(userDetail.getNickname());
        authorResponse.setSchoolName(userDetail.getSchoolName());
        authorResponse.setEmail(userDetail.getEmail());
        authorResponse.setSchoolId(userDetail.getSchoolId());
        authorResponse.setUserIntroduction(userDetail.getUserIntroduction());
        authorResponse.setUserImage(userDetail.getUserImage());
        authorResponse.setUserCollege(userDetail.getUserCollege());
        authorResponse.setUserType(userDetail.getUserType());
        authorResponse.setRealname(userDetail.getRealname());
        authorResponse.setSex(userDetail.getSex());
        authorResponse.setUserGrade(userDetail.getUserGrade());
        authorResponse.setUserMajor(userDetail.getUserMajor());
        authorResponse.setUserMobile(userDetail.getUserMobile());
        authorResponse.setUserCover(userDetail.getUserCover());

        return authorResponse;  // 返回包含所有信息的 AiXAuthorResponse 对象
    }



    /**
     * @Author ZhangBo
     * @Description 获取文件后缀
     * @Date 16:05 2025/1/15
     * @Param [fileName]
     * @return java.lang.String
     **/
    private String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf('.');
        return dotIndex == -1 ? "" : fileName.substring(dotIndex);
    }

    /**
     * @Author ZhangBo
     * @Description 有关标签的统一处理
     * @Date 9:56 2025/1/17
     * @Param [tags, sceneId]
     * @return void
     **/
    private void handleTags(List<String> tags, Long sceneId) {
        for (String tag : tags) {
            // 检查标签是否已存在
            AiXTag existingTag = aiXTagMapper.selectOne(new LambdaQueryWrapper<AiXTag>().eq(AiXTag::getTagName, tag).last("LIMIT 1"));
            Long tagId;
            if (existingTag == null) {
                // 标签不存在，生成随机ID并插入新标签
                tagId = new SnowflakeIdGenerator(1, 1).nextId();
                AiXTag newTag = new AiXTag();
                newTag.setTagId(tagId);
                newTag.setTagName(tag);
                aiXTagMapper.insert(newTag); // 插入新标签
            } else {
                // 标签已存在，使用现有的tagId
                tagId = existingTag.getTagId();
            }

            // 在连接表中插入关联
            AiXTagConnect tagConnect = new AiXTagConnect();
            tagConnect.setConnectId(new SnowflakeIdGenerator(1, 1).nextId()); // 生成连接表主键
            tagConnect.setConnectTable("ai_x_scene");
            tagConnect.setConnectTableKey(sceneId);
            tagConnect.setTagId(tagId);
            aiXTagConnectMapper.insert(tagConnect); // 插入关联
        }
    }


}




